/***************************************************************************
 *   Copyright (C) 2009 by Michael Oates   *
 *   michael@michael-laptop   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
//#include "video.h"

#include <system.h>
#include <video.h>
#include <printf.h>

/* You will need to code these up yourself!  */
unsigned char *memcpy(void *dest, const void *src, int count)
{
	char *dp = (char *)dest;
	const char *sp = (const char *)src;
	while (count>0)
	{
		*dp++=*sp++;
		count--;
	}
	return dest;
}

unsigned char *memset(unsigned char *dest, unsigned char val, int count)
{
	unsigned char *dp = (unsigned char *)dest;
    	while (count>0)
	{
		*dp++=val;
		count--;
	}
	return dest;
}

unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
{
    	unsigned short *dp = (unsigned short *)dest;
    	while (count>0)
	{
		*dp++=val;
		count--;
	}
	return dest;
}

/* We will use this later on for reading from the I/O ports to get data
*  from devices such as the keyboard. We are using what is called
*  'inline assembly' in these routines to actually do the work */
unsigned char inportb (unsigned short _port)
{
    unsigned char rv;
    __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
    return rv;
}

/* We will use this to write to I/O ports to send bytes to devices. This
*  will be used in the next tutorial for changing the textmode cursor
*  position. Again, we use some inline assembly for the stuff that simply
*  cannot be done in C */
void outportb (unsigned short _port, unsigned char _data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}

void PANIC (char *str)
{
	printf(str);
	__asm__ __volatile__("cli");
	draw_box(43,0,34,25,1,0x01);
	draw_textat(45,2,0x1F,"Software Panic!\0");
	draw_textat(45,3,0x1F,"The kernel has hit an error:\0");
	draw_textat(45,5,0x1F,str);
	for (;;);
}

int main(void)
{
	int a, b;
	int* c;
	a = b =5;
	/* You would add commands after here */

    /* ...and leave this loop in. There is an endless loop in
    *  'start.asm' also, if you accidentally delete this next line */
    init_video();
	printf("|  | /--\\  /--- ----     /--\  /---            \n\0");
	printf("|--| |  |  \\--\\  ||      |  |  \\--\\            \n\0");
	printf("|  | \\--/  ---/  ||      \\--/  ---/     v0.0.01\n\0");
    gdt_install();
	printf("[%03i] GDT Started\n\0",1);
    idt_install();
	printf("[%03i] IDT Started\n\0",2);
    isrs_install();
	printf("[%03i] ISR Started\n\0",3);
    irq_install();
	printf("[%03i] IRQ Started\n\0",4);
    __asm__ __volatile__ ("sti");
    	printf("[%03i] Interupts Unmasked\n\0",5);
    timer_install();
	printf("[%03i] Timer installed\n\0",6);
    keyboard_install();
	printf("[%03i] Keyboard installed\n\0",7);
    initialise_paging();
	printf("[%03i] Paging Started\n\0",8);
	printf("-->\0");
    a=5/0;
    putch(a);
    for (;;);
} 